<template>
  <div>
    <avue-crud
      ref="crud"
      v-if="option.column"
      :data="data.data"
      :page.sync="page"
      :option="option"
      v-model="form"
      @row-save="save"
      @row-update="update"
      @row-del="remove"
      @on-load="changePage"
      @sort-change="changeSort"
      @search-change="changeSearch"
      :upload-before="uploadBefore"
    ></avue-crud>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from "vue-property-decorator";
interface page {
  pageSize: Number;
  pageSizes: Array<Number>;
  total: Number;
}
interface row {
  _id: string;
}
interface done {
  (): void;
}
interface query {
  page: Number;
  limit: Number;
  sort: any;
  where: any;
}
interface changePage {
  pageSize: Number;
  currentPage: Number;
}
interface changeSort {
  prop: any;
  order: String;
}

@Component
export default class ResourceList extends Vue {
  @Prop(String) resource!: string;
  data: any = {};
  option: any = {};
  page: page = {
    pageSize: 10,
    pageSizes: [2, 5, 10, 15],
    total: 1,
  };
  query: query = {
    page: 1,
    limit: 10,
    sort: null,
    where: {},
  };
  form: any = {};
  async fetchOption() {
    const res = await this.$http.get(`${this.resource}/option`);
    this.option = res.data;
  }
  async fetch() {
    const res = await this.$http.get(`${this.resource}`, {
      // axios自动转为字符串
      params: {
        query: this.query,
      },
    });
    this.page.total = res.data.total;
    this.data = res.data;
  }
  // 创建
  async save(row: row, done: done) {
    await this.$http.post(`${this.resource}`, row);
    this.$message.success("创建成功");
    this.fetch();
    done();
  }
  // 更新
  async update(row: row, index: string, done: done) {
    const data = JSON.parse(JSON.stringify(row));
    // mongoDB中 对$开头较敏感 无法处理 因此删除掉$index键
    delete data.$index;
    await this.$http.put(`${this.resource}/${row._id}`, data);
    this.$message.success("更新成功");
    this.fetch();
    done();
  }
  // 删除
  async remove(row: row) {
    try {
      await this.$confirm("是否确认删除");
    } catch (error) {
      return;
    }
    await this.$http.delete(`${this.resource}/${row._id}`);
    this.$message.success("删除成功");
    this.fetch();
  }
  // 切换页数
  async changePage({ pageSize, currentPage }: changePage) {
    this.query.page = currentPage;
    this.query.limit = pageSize;
    this.fetch();
  }
  // 服务端排序
  async changeSort({ prop, order }: changeSort) {
    if (!order) {
      this.query.sort = null;
    } else {
      this.query.sort = {
        [prop]: order === "ascending" ? "1" : "-1",
      };
    }
    this.fetch();
  }
  // 搜索
  async changeSearch(where: Object, done: done) {
    // 遍历判断是否为模糊搜索
    for (let k in where) {
      const field = this.option.column.find((v) => v.prop === k);
      if (field.regex) {
        // 模糊搜索
        where[k] = { $regex: where[k] };
      }
    }
    this.query.where = where;
    this.fetch();
    done();
  }
  // 图片上传前
  async uploadBefore(file, done) {
    const formData = new FormData();
    formData.append("file", file);
    const res = await this.$http.post("upload", formData);
    for (let k in this.form) {
      if (k === "cover") {
        this.form.cover = res.data.url;
      } else {
        this.form.file = res.data.url;
      }
    }

    this.$message.success("上传成功成功");
    done();
  }
  created() {
    this.fetchOption();
    this.fetch();
  }
}
</script>

<style lang="scss" scope></style>
